package com.whiteape.book.ui.fragment;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.didikee.donate.AlipayDonate;
import android.didikee.donate.WeiXinDonate;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.appcompat.widget.Toolbar;

import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.hwangjr.rxbus.RxBus;
import com.meituan.android.walle.WalleChannelReader;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.tencent.bugly.beta.Beta;
import com.whiteape.book.R;

import com.whiteape.book.common.RxEvent;
import com.whiteape.book.core.manager.MediaStorageManager;
import com.whiteape.book.core.manager.ReadSettingManager;
import com.whiteape.book.core.manager.SiteSourceManager;
import com.whiteape.book.core.page.PageStyleNew;
import com.whiteape.book.model.dto.CollectionMediaBean;
import com.whiteape.book.model.dto.MediaRecordBean;
import com.whiteape.book.model.dto.SiteSourceBean;
import com.whiteape.book.model.type.WebviewDocType;
import com.whiteape.book.ui.activity.AboutActivity;
import com.whiteape.book.ui.activity.DownloadActivity;
import com.whiteape.book.ui.activity.MainActivity;
import com.whiteape.book.ui.activity.SettingsActivity;
import com.whiteape.book.ui.activity.SiteSourceManageActivity;
import com.whiteape.book.ui.activity.WebviewActivity;
import com.whiteape.book.ui.base.BaseFragment;
import com.whiteape.book.utils.AppUtils;
import com.whiteape.book.utils.FileUtils;
import com.whiteape.book.utils.GlideCacheUtil;
import com.whiteape.book.utils.GsonUtils;
import com.whiteape.book.utils.JumpPermissionManagement;
import com.whiteape.book.utils.RxUtils;
import com.whiteape.book.utils.ShareUtil;
import com.whiteape.book.utils.StringUtils;
import com.whiteape.book.utils.ToastUtils;
import com.whiteape.book.utils.ZipUtils2;
import com.whiteape.book.utils.web_dav.WebDavFile;
import com.whiteape.book.utils.web_dav.WebDavHelp;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import io.reactivex.Single;
import io.reactivex.disposables.Disposable;

public class MineFragment extends BaseFragment implements View.OnClickListener {

    @BindView(R.id.rl_mine_download)
    RelativeLayout rlMineDownload;

    @BindView(R.id.rl_mine_site_source)
    RelativeLayout rlMineSiteSource;

    @BindView(R.id.rl_mine_clear_cache)
    RelativeLayout rlClearCache;

    @BindView(R.id.rl_mine_check_upgrade)
    RelativeLayout rlCheckUpgrade;

    @BindView(R.id.rl_mine_common_settings)
    RelativeLayout rlCommonSettings;

    @BindView(R.id.rl_mine_qq_group)
    RelativeLayout rlQQGroup;

    @BindView(R.id.rl_mine_about)
    RelativeLayout rlAbout;

    @BindView(R.id.mine_tv_cache_size)
    TextView tvCacheSize;

    @BindView(R.id.tv_version)
    TextView tvVersion;

    @BindView(R.id.rl_mine_share)
    RelativeLayout rlShare;

    @BindView(R.id.rl_mine_qa)
    RelativeLayout rlQa;

    @BindView(R.id.rl_mine_save_restore)
    RelativeLayout rlSaveResotre;
    @BindView(R.id.rl_mine_settings)
    RelativeLayout rlSettings;

    @BindView(R.id.rl_mine_donate)
    RelativeLayout rlDonate;

    final private int OP_TYPE_SAVE = 0;

    final private int OP_TYPE_RESTORE = 1;
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    Disposable disposable;

    private static final String BACK_UP_ZIP_FILE_NAME = "backup.zip";
    private static final String RESTORE_UP_ZIP_FILE_NAME = "backup.zip";

    @Override
    protected int getContentId() {
        return R.layout.fragment_mine;
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        super.initView(savedInstanceState);
//        if (getContext() != null) {
//            toolbar.setBackgroundColor(getContext().getResources().getColor(R.color.colorAccent));
//        }
        tvCacheSize.setText(GlideCacheUtil.getInstance().getCacheSize(getContext()));
        tvVersion.setText("当前:" + AppUtils.getVersionName(getContext()));
        Context context = getContext();
        if (context == null) {
            return;
        }
        String channel = WalleChannelReader.getChannel(context);
        if (StringUtils.isEmpty(channel)) {
            channel = "d_" + context.getPackageName() + "_" + AppUtils.getVersionCode(getContext()) + "_" + AppUtils.getVersionName(context);
        }

        if (channel.equals("52pojie") || channel.equals("huluxia")) {
            rlQQGroup.setVisibility(View.GONE);
        } else {
            rlQQGroup.setVisibility(View.VISIBLE);
        }

        rlQQGroup.setVisibility(View.GONE);
        rlDonate.setVisibility(View.GONE);
    }

    @Override
    protected void initEvent() {
        super.initEvent();
        rlCheckUpgrade.setOnClickListener(this);
        rlClearCache.setOnClickListener(this);
        rlCommonSettings.setOnClickListener(this);
        rlAbout.setOnClickListener(this);
        rlMineDownload.setOnClickListener(this);
        rlMineSiteSource.setOnClickListener(this);
        rlQQGroup.setOnClickListener(this);
        rlQa.setOnClickListener(this);
        rlSaveResotre.setOnClickListener(this);
        rlDonate.setOnClickListener(this);
        rlShare.setOnClickListener(this);
        rlSettings.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.rl_mine_site_source:
                startActivity(new Intent(getContext(), SiteSourceManageActivity.class));
                break;
            case R.id.rl_mine_check_upgrade:
                Beta.checkUpgrade();
                break;
            case R.id.rl_mine_clear_cache:
                if (getContext() == null) {
                    return;
                }
                new AlertDialog.Builder(getContext())
                        .setTitle(StringUtils.getString(R.string.wa_common_tip))
                        .setMessage(R.string.sure_to_clear_cache)
                        .setTitle(StringUtils.getString(R.string.wa_common_tip))
                        .setNegativeButton(R.string.wa_common_cancel, (dialog, which) -> dialog.dismiss())
                        .setPositiveButton(R.string.wa_common_sure, ((dialog, which) -> {
                            GlideCacheUtil.getInstance().clearImageAllCache(getContext());
                            ToastUtils.show("缓存清理完毕");
                            tvCacheSize.setText("0KB");
                        }))
                        .show();
                break;
            case R.id.rl_mine_common_settings:
                break;
            case R.id.rl_mine_about:
                startActivity(new Intent(getContext(), AboutActivity.class));
                break;
            case R.id.rl_mine_qa:
                startActivity(new Intent(getContext(), WebviewActivity.class).putExtra(WebviewActivity.KEY_WEBVIEW_TYPE, WebviewDocType.WEBVIEW_DOC_TYPE_QA));
                break;
            case R.id.rl_mine_share:
                if (getActivity() != null) {
//                    ShareUtil.umShare(getActivity(), ((MainActivity) getActivity()));
                    ShareUtil.checkPermissionAndShareInFragment(this, (MainActivity) getActivity());
//                    ShareUtil.umShare();
//                    checkPermissionAndShare();
                }
                break;
            case R.id.rl_mine_save_restore:
                if (getActivity() != null) {
                    String[] choices = new String[]{"备份（网源和书架信息）", "恢复（可能会覆盖当前网源和书架信息）"};
                    new AlertDialog.Builder(getActivity())
                            .setTitle("请选择")
                            .setItems(choices, (dialog, which) -> {
                                if (which == 0) {
                                    checkPermissionAndSaveOrRecord(OP_TYPE_SAVE);
                                } else {
                                    checkPermissionAndSaveOrRecord(OP_TYPE_RESTORE);
                                }

                            }).show();
                }
                break;

            case R.id.rl_mine_download:
                startActivity(new Intent(getContext(), DownloadActivity.class));
                break;
            case R.id.rl_mine_donate:
//                startActivity(new Intent(getContext(), DonateActivity.class));
                showDonateDialog();
                break;
            case R.id.rl_mine_qq_group:
                joinQQGroup("lrmA53k2SpX_lL8Q0R4ey8fGYPLWcJSz");
                break;
            case R.id.rl_mine_settings:
                startActivity(new Intent(getContext(), SettingsActivity.class));
                break;

        }

    }

    private void showDonateDialog() {
        Activity activity = getActivity();
        if (activity == null) {
            return;
        }
        View view = View.inflate(getActivity(), R.layout.donate_popup, null);
        BottomSheetDialog dialog = new BottomSheetDialog(activity);
        dialog.setContentView(view);
        View alipayView = view.findViewById(R.id.ll_alipay);
        View wechatPayView = view.findViewById(R.id.ll_wechat_pay);
        View cancelView = view.findViewById(R.id.btn_cancel);
        alipayView.setOnClickListener(v -> {

            donateAlipay(activity);
        });
        wechatPayView.setOnClickListener(v -> {
            donateWeixin(activity);


        });
        cancelView.setOnClickListener(v -> {
            dialog.cancel();
        });

        dialog.show();
    }

    private void donateAlipay(Activity activity) {
        String alipayCode = "fkx092556rbscz1p58gb9ef";
        boolean hasInstalledAlipayClient = AlipayDonate.hasInstalledAlipayClient(activity);
        if (hasInstalledAlipayClient) {

            AlipayDonate.startAlipayClient(activity, alipayCode);
        }
    }

    private void donateWeixin(Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity)
                .setTitle(R.string.wa_common_tip)
                .setMessage("需要在微信扫描界面打开系统相册选择第一张图片")
                .setPositiveButton(R.string.wa_common_ok, (dialog, which) -> {
                    dialog.dismiss();
                    InputStream weixinQrIs = getResources().openRawResource(R.raw.wechatpay_qrcode);
                    String qrPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "whiteape" + File.separator +
                            "whiteape_weixin.png";
                    WeiXinDonate.saveDonateQrImage2SDCard(qrPath, BitmapFactory.decodeStream(weixinQrIs));
                    WeiXinDonate.donateViaWeiXin(activity, qrPath);
                });
        builder.show();


    }


    /****************
     *
     * 发起添加群流程。群号：白猿搜书①群(868153326) 的 key 为： PQEP02boUOUiq_0hcdj2pO1UlybAx7zN
     * 调用 joinQQGroup(PQEP02boUOUiq_0hcdj2pO1UlybAx7zN) 即可发起手Q客户端申请加群 白猿搜书①群(868153326)
     *
     * @param key 由官网生成的key
     * @return 返回true表示呼起手Q成功，返回fals表示呼起失败
     ******************/
    public boolean joinQQGroup(String key) {
        Intent intent = new Intent();
        intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
        // 此Flag可根据具体产品需要自定义，如设置，则在加群界面按返回，返回手Q主界面，不设置，按返回会返回到呼起产品界面    //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        try {
            startActivity(intent);
            return true;
        } catch (Exception e) {
            // 未安装手Q或安装的版本不支持
            return false;
        }
    }

    private void rxPermissionRequest(RxPermissions rxPermissions, int type) {
        String permissionRequired = Manifest.permission.WRITE_EXTERNAL_STORAGE;
        boolean useWebDav = ReadSettingManager.getInstance().getBackupUseWebDav();
        disposable = rxPermissions.requestEach(permissionRequired)
                .subscribe(permission -> {
                    if (permission.granted) {
                        // `permission.name` is granted !
                        if (type == OP_TYPE_SAVE) {
                            saveRecord(useWebDav);
                        } else {
                            restore(useWebDav);
                        }

                    } else if (permission.shouldShowRequestPermissionRationale) {
                        // Denied permission without ask never again
                        if (getContext() == null) {
                            ToastUtils.show("必须授权才能下一步操作哦");
                            return;
                        }
//                        importSiteSourceBy(type);
                        new androidx.appcompat.app.AlertDialog.Builder(getContext())
                                .setTitle(R.string.wa_common_tip)
                                .setMessage(R.string.permission_request_sdcard)
                                .setPositiveButton(R.string.wa_common_sure, ((dialogInterface, i) -> {
                                    dialogInterface.dismiss();
                                    rxPermissionRequest(rxPermissions, type);
                                }))
                                .setNegativeButton(R.string.wa_common_cancel, ((dialogInterface, i) -> {
                                    dialogInterface.dismiss();
                                    ToastUtils.show("已经拒绝权限，需要重新打开授权才可以备份/恢复哦");
                                })).show();
                    } else {
                        // Denied permission with ask never again
                        // Need to go to the settings
                        if (getContext() == null) {
                            ToastUtils.show("已经拒绝权限，需要去系统设置打开权限哦");
                            return;
                        }
                        new androidx.appcompat.app.AlertDialog.Builder(getContext())
                                .setTitle(R.string.wa_common_tip)
                                .setMessage(R.string.permission_request_sdcard_goto_setting)
                                .setPositiveButton(R.string.wa_common_sure, ((dialogInterface, i) -> {
                                    //goto setting
                                    dialogInterface.dismiss();
                                    JumpPermissionManagement.goToSetting(getActivity());

                                }))
                                .setNegativeButton(R.string.wa_common_cancel, ((dialogInterface, i) -> {
                                    dialogInterface.dismiss();
                                    ToastUtils.show("已拒绝权限，无法导入图片");
                                })).show();

                    }
                });

    }


    private void checkPermissionAndSaveOrRecord(int type) {

        boolean useWebDav = ReadSettingManager.getInstance().getBackupUseWebDav();
        RxPermissions rxPermissions = new RxPermissions(this);
        if (rxPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            if (type == OP_TYPE_SAVE) {
                saveRecord(useWebDav);
            } else {
                restore(useWebDav);
            }
            return;
        }
        if (getContext() == null) {
            return;
        }
        new androidx.appcompat.app.AlertDialog.Builder(getContext())
                .setTitle(R.string.wa_common_tip)
                .setMessage(R.string.permission_request_sdcard)
                .setPositiveButton(R.string.wa_common_sure, ((dialogInterface, i) -> {
                    dialogInterface.dismiss();

                    rxPermissionRequest(rxPermissions, type);
                }))
                .setNegativeButton(R.string.wa_common_cancel, ((dialogInterface, i) -> {
                    dialogInterface.dismiss();
                    ToastUtils.show("已经拒绝权限，需要重新打开授权才可以进行备份/恢复哦");
                })).show();
    }


    private void showConfirmDialog(String message) {
        new AlertDialog.Builder(getContext())
                .setTitle("提示")
                .setMessage(message)
                .setPositiveButton("确认", (dialog, which) -> {

                }).show();
    }


    private Single<Boolean> saveRecordInRx(boolean isWebBackup) {
        return Single.create(emitter -> {

            //1. 源  2. 书架 3. 阅读记录 4.小说背景及文字颜色 5.字体？

            //判断读写sdcard权限

            try {
                //兼容老版本
                //如果没有backup文件夹但是有/sdcard/白猿搜书/xxx.was之类的，先把他们放到backup下

                List<SiteSourceBean> siteSourceBeanList = SiteSourceManager.getInstance().getSiteSourceAll();
                String jsonStr = GsonUtils.obj2String(siteSourceBeanList);

                List<CollectionMediaBean> collectionMediaBeanList = MediaStorageManager.getInstance().getCollectionMediaList();
                String collectionMediaStr = GsonUtils.obj2String(collectionMediaBeanList);

                List<MediaRecordBean> mediaRecordBeanList = new ArrayList<>(collectionMediaBeanList.size());
                String mediaRecordStr = GsonUtils.obj2String(mediaRecordBeanList);


                PageStyleNew pageStyleNew = ReadSettingManager.getInstance().getPageStyleNew();
                List<PageStyleNew> pageStyleNewList = ReadSettingManager.getInstance().getPageStyleAll();
                String pageStyleListStr = GsonUtils.obj2String(pageStyleNewList);
                String pageCurrentStr = GsonUtils.obj2String(pageStyleNew);


                //TODO 兼容老的，新的放到 /sdcard/白猿搜书/backup/下
                //新版本一进来，就判断/sdcard/白猿搜书/下有没有文件，有的话放到backup下
//                FileUtils.migrateBackupFiles();
                String oldSavePath = FileUtils.getOldSavePath();
                String savePath = FileUtils.getSavePath();

                FileUtils.saveFile(new ByteArrayInputStream(jsonStr.getBytes()), savePath + File.separator + "source.was");
                FileUtils.saveFile(new ByteArrayInputStream(collectionMediaStr.getBytes()), savePath + File.separator + "coll.wac");
                FileUtils.saveFile(new ByteArrayInputStream(mediaRecordStr.getBytes()), savePath + File.separator + "read_record.war");
                FileUtils.saveFile(new ByteArrayInputStream(pageStyleListStr.getBytes()), savePath + File.separator + "pstyle.waps");
                FileUtils.saveFile(new ByteArrayInputStream(pageCurrentStr.getBytes()), savePath + File.separator + "pstyle.wapc");

                if (isWebBackup) {
                    saveWithWebDav();
                }
                emitter.onSuccess(true);
            } catch (Exception e) {
                emitter.onError(e);
            }
        });
    }

    //备份 到/sdcard/白猿搜书/下
    private void saveRecord(boolean useWebDav) {
        addDisposable(saveRecordInRx(useWebDav).compose(RxUtils::toSimpleSingle)
                .subscribe(aBoolean -> {
                    if (aBoolean) {
                        showConfirmDialog("备份完成");
                    } else {
                        showConfirmDialog("备份失败!");
                    }
                }, throwable -> {
                    throwable.printStackTrace();
                    showConfirmDialog("备份失败!" + throwable.getLocalizedMessage());
                }));

    }

    private boolean saveWithWebDav() throws Exception{

        //如果webdav,上传zip
            String zipFilePath = FileUtils.getOldSavePath() + File.separator + BACK_UP_ZIP_FILE_NAME;
            ZipUtils2.zipFolder(FileUtils.getSavePath(), zipFilePath);
            if (WebDavHelp.initWebDav()) {
                new WebDavFile(WebDavHelp.getWebDavUrl() + "BaiYuan").makeAsDir();
//                String putUrl = WebDavHelp.getWebDavUrl() + "BaiYuan/backup" + TimeUtils.date2String(TimeUtils.getNowDate(), new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())) + ".zip";
                String putUrl = WebDavHelp.getWebDavUrl() + "BaiYuan/backup.zip";
                WebDavFile webDavFile = new WebDavFile(putUrl);
                webDavFile.upload(zipFilePath);
                return true;
            }else{
//                ToastUtils.show("初始化失败，请检查账户密码");
                return false;
            }

//        } catch (Exception e) {
//            e.printStackTrace();
//            ToastUtils.show("出现了点问题 + " + e.getMessage());
//        }
//        return false;
    }

    private boolean restoreWithWebDav() throws Exception{
            if (WebDavHelp.initWebDav()) {
                String restoreFilePath = FileUtils.getOldSavePath() + File.separator + RESTORE_UP_ZIP_FILE_NAME;
                WebDavFile webDavFile = new WebDavFile(WebDavHelp.getWebDavUrl() + "BaiYuan/backup.zip");
                webDavFile.download(restoreFilePath, true);
                ZipUtils2.unZipFolder(restoreFilePath, FileUtils.getSavePath());
                return true;
            }else{
//                ToastUtils.show("初始化失败，请检查账户密码");
                return false;
            }
//        }
//        catch (Exception e){
//            e.printStackTrace();
//            ToastUtils.show("还原失败，" + e.getMessage());
//        }
    }

    private Single<Boolean> restoreInRx(boolean useWebDav) {

        return Single.create(emitter -> {
            //1. 源  2. 书架 3. 阅读记录 4.背景  5.字体
            if(useWebDav){
                try {
                    if (!restoreWithWebDav()) {
                        emitter.onSuccess(false);
                        return;
                    }
                }catch (Exception e){
                    emitter.onError(e);
                    return;
                }
            }
//            FileUtils.migrateBackupFiles();
            String savePath = FileUtils.getSavePath();
            File sourceFile = new File(savePath + File.separator + "source.was");
            if (!sourceFile.exists()) {
                emitter.onSuccess(false);
            }
            String sourceStr = FileUtils.readFile(sourceFile);
            boolean importSourceResult = SiteSourceManager.getInstance().importSiteSourceByWas(sourceStr);
            if (!importSourceResult) {
                emitter.onSuccess(false);
            }

            File collectionFile = new File(savePath + File.separator + "coll.wac");
            if (!collectionFile.exists()) {
                emitter.onSuccess(false);
            }

            File pageStyleAllFile = new File(savePath + File.separator + "pstyle.waps");
            File pageStyleCurFile = new File(savePath + File.separator + "pstyle.wapc");
            if (!pageStyleAllFile.exists() || !pageStyleCurFile.exists()) {
                emitter.onSuccess(false);
            }


            String collectionStr = FileUtils.readFile(collectionFile);

            List<CollectionMediaBean> collectionMediaBeanList = GsonUtils.string2List(collectionStr, CollectionMediaBean.class);
            for (CollectionMediaBean mediaBean : collectionMediaBeanList) {
                MediaStorageManager.getInstance().saveCollectionMedia(mediaBean);
            }


            File readRecordFile = new File(savePath + File.separator + "read_record.war");
            if (!readRecordFile.exists()) {
                emitter.onSuccess(false);
            }
            String readRecordStr = FileUtils.readFile(readRecordFile);
            List<MediaRecordBean> mediaRecordBeanList = GsonUtils.string2List(readRecordStr, MediaRecordBean.class);
            for (MediaRecordBean mediaRecordBean : mediaRecordBeanList) {
                MediaStorageManager.getInstance().saveMediaRecord(mediaRecordBean);
            }

            String pageStyleAll = FileUtils.readFile(pageStyleAllFile);
            String pageStyleCur = FileUtils.readFile(pageStyleCurFile);
            PageStyleNew pageStyleNew = GsonUtils.string2Obj(pageStyleCur, PageStyleNew.class);

            List<PageStyleNew> currentPageStyleList = GsonUtils.string2List(pageStyleAll, PageStyleNew.class);

            ReadSettingManager.getInstance().setPageStyleNew(pageStyleNew);
            ReadSettingManager.getInstance().setPageStyleAll(currentPageStyleList);

            RxBus.get().post(RxEvent.READ_PAGE_STYLE_CHANGED, pageStyleNew);

            RxBus.get().post(RxEvent.MEDIA_COLLECTION_REFRESH, new CollectionMediaBean());
            emitter.onSuccess(true);

        });

    }

    //恢复
    private void restore(boolean useWebDav) {
        addDisposable(restoreInRx(useWebDav)

                .compose(RxUtils::toSimpleSingle)
                .subscribe(b -> {
                    if (b) {
                        RxBus.get().post(RxEvent.SITE_SOURCE_ADDED, "");
                        showConfirmDialog("恢复成功");
                    }else{

                    }

                }, throwable -> {
                    showConfirmDialog("恢复失败," + throwable.getLocalizedMessage());
                }));

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}
